package com.smartcampusbackend.config;

import com.smartcampusbackend.model.User;
import com.smartcampusbackend.service.SystemLogService;
import com.smartcampusbackend.service.TokenService;
import com.smartcampusbackend.service.UserService;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import java.io.BufferedReader;
import java.io.IOException;
import java.util.stream.Collectors;

@Component
@Slf4j
public class LogInterceptor implements HandlerInterceptor {
    
    @Autowired
    private SystemLogService systemLogService;
    
    @Autowired
    private TokenService tokenService;
    
    @Autowired
    private UserService userService;
    
    private static final String START_TIME = "requestStartTime";
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 记录请求开始时间
        request.setAttribute(START_TIME, System.currentTimeMillis());
        return true;
    }
    
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        try {
            // 获取请求开始时间
            Long startTime = (Long) request.getAttribute(START_TIME);
            if (startTime == null) {
                return;
            }
            
            // 计算执行时间
            long executionTime = System.currentTimeMillis() - startTime;
            
            // 获取请求信息
            String requestUrl = request.getRequestURL().toString();
            String requestMethod = request.getMethod();
            String ipAddress = getClientIpAddress(request);
            String userAgent = request.getHeader("User-Agent");
            int responseStatus = response.getStatus();
            
            // 获取请求参数
            String requestParams = getRequestParams(request);
            
            // 获取当前用户信息
            User currentUser = getCurrentUser(request);
            
            // 跳过不需要记录的请求
            if (shouldSkipLogging(requestUrl)) {
                return;
            }
            
            // 根据响应状态和异常情况记录不同类型的日志
            if (ex != null) {
                // 记录错误日志
                if (currentUser != null) {
                    systemLogService.logError(
                        currentUser.getUsername(),
                        currentUser.getId(),
                        requestMethod + " " + requestUrl,
                        "请求处理异常: " + ex.getMessage(),
                        ipAddress,
                        userAgent,
                        requestUrl,
                        requestMethod,
                        requestParams,
                        responseStatus,
                        ex.getMessage(),
                        executionTime
                    );
                }
            } else if (responseStatus >= 400) {
                // 记录失败日志
                if (currentUser != null) {
                    systemLogService.logOperation(
                        currentUser.getUsername(),
                        currentUser.getId(),
                        requestMethod + " " + requestUrl,
                        "请求处理失败，状态码: " + responseStatus,
                        ipAddress,
                        userAgent,
                        requestUrl,
                        requestMethod,
                        requestParams,
                        responseStatus,
                        executionTime,
                        "FAILED"
                    );
                }
            } else {
                // 记录成功日志
                if (currentUser != null) {
                    systemLogService.logOperation(
                        currentUser.getUsername(),
                        currentUser.getId(),
                        requestMethod + " " + requestUrl,
                        "请求处理成功",
                        ipAddress,
                        userAgent,
                        requestUrl,
                        requestMethod,
                        requestParams,
                        responseStatus,
                        executionTime,
                        "SUCCESS"
                    );
                }
            }
        } catch (Exception e) {
            log.error("记录请求日志失败", e);
        }
    }
    
    /**
     * 获取客户端真实IP地址
     */
    private String getClientIpAddress(HttpServletRequest request) {
        String xForwardedFor = request.getHeader("X-Forwarded-For");
        if (xForwardedFor != null && !xForwardedFor.isEmpty() && !"unknown".equalsIgnoreCase(xForwardedFor)) {
            return xForwardedFor.split(",")[0].trim();
        }
        
        String xRealIp = request.getHeader("X-Real-IP");
        if (xRealIp != null && !xRealIp.isEmpty() && !"unknown".equalsIgnoreCase(xRealIp)) {
            return xRealIp;
        }
        
        return request.getRemoteAddr();
    }
    
    /**
     * 获取请求参数
     */
    private String getRequestParams(HttpServletRequest request) {
        try {
            // 获取查询参数
            String queryString = request.getQueryString();
            
            // 获取POST请求体（仅对JSON请求）
            String contentType = request.getContentType();
            if (contentType != null && contentType.contains("application/json")) {
                try (BufferedReader reader = request.getReader()) {
                    String body = reader.lines().collect(Collectors.joining());
                    if (body != null && !body.isEmpty()) {
                        return body.length() > 500 ? body.substring(0, 500) + "..." : body;
                    }
                } catch (IOException e) {
                    log.warn("读取请求体失败", e);
                }
            }
            
            return queryString != null ? queryString : "";
        } catch (Exception e) {
            log.warn("获取请求参数失败", e);
            return "";
        }
    }
    
    /**
     * 获取当前登录用户信息
     */
    private User getCurrentUser(HttpServletRequest request) {
        try {
            String token = request.getHeader("Authorization");
            if (token != null && token.startsWith("Bearer ")) {
                token = token.substring(7);
                String username = tokenService.getUsernameByToken(token);
                if (username != null) {
                    return userService.getByUsername(username);
                }
            }
        } catch (Exception e) {
            log.warn("获取当前用户信息失败", e);
        }
        return null;
    }
    
    /**
     * 判断是否需要跳过日志记录
     */
    private boolean shouldSkipLogging(String requestUrl) {
        // 跳过静态资源请求
        if (requestUrl.contains("/static/") || 
            requestUrl.contains("/css/") || 
            requestUrl.contains("/js/") || 
            requestUrl.contains("/images/") ||
            requestUrl.contains("/favicon.ico")) {
            return true;
        }
        
        // 跳过健康检查等系统接口
        if (requestUrl.contains("/actuator/") || 
            requestUrl.contains("/health") ||
            requestUrl.contains("/metrics")) {
            return true;
        }
        
        return false;
    }
} 